package com.google.gwt.user.rebind.rpc;

import com.google.gwt.core.ext.Generator;
import com.google.gwt.core.ext.GeneratorContext;
import com.google.gwt.core.ext.TreeLogger;
import com.google.gwt.core.ext.UnableToCompleteException;
import com.google.gwt.core.ext.typeinfo.JClassType;
import com.google.gwt.core.ext.typeinfo.TypeOracle;

/**
 * Custom generator for producing the asynchronous client-side implementation
 * of a {@link com.google.gwt.user.client.rpc.RemoteService RemoteService}
 * interface.
 * <p>
 * The resulting service implementation can be customized via annotations:
 * <ul>
 * <li>{@link com.seventhdawn.gwt.rcx.client.annotation.ClientProxySuperclass
 * ClientProxySuperclass}
 * <li>{@link com.seventhdawn.gwt.rcx.client.annotation.CustomSerializableRoots
 * CustomSerializableRoots}
 * </ul>
 * <p>
 * Note that this generator delegates client-side proxy creation to
 * {@link UberProxyCreator}.
 * 
 * @see UberProxyCreator
 * @author various
 */
public class UberServiceInterfaceProxyGenerator extends Generator {
    
    @Override
    public String generate(TreeLogger logger, GeneratorContext ctx,
            String requestedClass) throws UnableToCompleteException {
        
        TypeOracle typeOracle = ctx.getTypeOracle();
        assert (typeOracle != null);
        
        JClassType remoteService = typeOracle.findType(requestedClass);
        if (remoteService == null) {
            logger.log(TreeLogger.ERROR, "Unable to find metadata for type '"
                    + requestedClass + "'", null);
            throw new UnableToCompleteException();
        }
        
        if (remoteService.isInterface() == null) {
            logger.log(TreeLogger.ERROR, remoteService.getQualifiedSourceName()
                    + " is not an interface", null);
            throw new UnableToCompleteException();
        }
        
        UberProxyCreator proxyCreator = new UberProxyCreator(remoteService);
        
        TreeLogger proxyLogger = logger.branch(TreeLogger.DEBUG,
                "Generating client proxy for remote service interface '"
                        + remoteService.getQualifiedSourceName() + "'", null);
        
        return proxyCreator.create(proxyLogger, ctx);
    }
    
}
